/**
 * 
 */
package com.star.exception.entity;

import org.springframework.http.HttpStatus;
import org.springframework.util.ObjectUtils;

/**
 * @ClassName: RestError
 * @Description: TODO
 * @author starhq
 * @createtime 2014年9月7日 下午5:33:03
 * @email : jian.wang@shinsoft.net
 * @modify by TODO
 * @resaon
 * @edittime
 * @version 1.0
 * @copyright
 */
public class RestError {
	private final HttpStatus status;
	private final int code;
	private final String message;
	private final String developerMessage;
	private final String moreInfoUrl;
	private final Throwable throwable;

	public RestError(HttpStatus status, int code, String message,
			String developerMessage, String moreInfoUrl, Throwable throwable) {
		if (status == null) {
			throw new NullPointerException(
					"HttpStatus argument cannot be null.");
		}
		this.status = status;
		this.code = code;
		this.message = message;
		this.developerMessage = developerMessage;
		this.moreInfoUrl = moreInfoUrl;
		this.throwable = throwable;
	}

	public HttpStatus getStatus() {
		return status;
	}

	public int getCode() {
		return code;
	}

	public String getMessage() {
		return message;
	}

	public String getDeveloperMessage() {
		return developerMessage;
	}

	public String getMoreInfoUrl() {
		return moreInfoUrl;
	}

	public Throwable getThrowable() {
		return throwable;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj instanceof RestError) {
			RestError re = (RestError) obj;
			return ObjectUtils.nullSafeEquals(getStatus(), re.getStatus())
					&& getCode() == re.getCode()
					&& ObjectUtils
							.nullSafeEquals(getMessage(), re.getMessage())
					&& ObjectUtils.nullSafeEquals(getDeveloperMessage(),
							re.getDeveloperMessage())
					&& ObjectUtils.nullSafeEquals(getMoreInfoUrl(),
							re.getMoreInfoUrl())
					&& ObjectUtils.nullSafeEquals(getThrowable(),
							re.getThrowable());
		}
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		// noinspection ThrowableResultOfMethodCallIgnored
		return ObjectUtils.nullSafeHashCode(new Object[] { getStatus(),
				getCode(), getMessage(), getDeveloperMessage(),
				getMoreInfoUrl(), getThrowable() });
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		// noinspection StringBufferReplaceableByString
		return new StringBuilder().append(getStatus().value()).append(" (")
				.append(getStatus().getReasonPhrase()).append(" )").toString();
	}

	public static class Builder {
		private HttpStatus status;
		private int code;
		private String message;
		private String developerMessage;
		private String moreInfoUrl;
		private Throwable throwable;

		public Builder() {
		}

		public Builder setStatus(int statusCode) {
			this.status = HttpStatus.valueOf(statusCode);
			return this;
		}

		public Builder setStatus(HttpStatus status) {
			this.status = status;
			return this;
		}

		public Builder setCode(int code) {
			this.code = code;
			return this;
		}

		public Builder setMessage(String message) {
			this.message = message;
			return this;
		}

		public Builder setDeveloperMessage(String developerMessage) {
			this.developerMessage = developerMessage;
			return this;
		}

		public Builder setMoreInfoUrl(String moreInfoUrl) {
			this.moreInfoUrl = moreInfoUrl;
			return this;
		}

		public Builder setThrowable(Throwable throwable) {
			this.throwable = throwable;
			return this;
		}

		public RestError build() {
			if (this.status == null) {
				this.status = HttpStatus.INTERNAL_SERVER_ERROR;
			}
			return new RestError(this.status, this.code, this.message,
					this.developerMessage, this.moreInfoUrl, this.throwable);
		}
	}
}
